package com.corpgovernment.travelstandard.convert;

import com.corpgovernment.api.travelstandard.bo.TrainTransferStandardDetailResponseBO;
import com.corpgovernment.api.travelstandard.enums.ReasonCodeTypeEnum;
import com.corpgovernment.api.travelstandard.enums.TravelStandardTypeEnum;
import com.corpgovernment.api.travelstandard.vo.Node;
import com.corpgovernment.api.travelstandard.vo.car.CarCityControl;
import com.corpgovernment.api.travelstandard.vo.car.ModelControl;
import com.corpgovernment.api.travelstandard.vo.car.PriceControl;
import com.corpgovernment.organization.entity.db.MbPostInfo;
import com.corpgovernment.travelstandard.dto.TrainTransferStandardDTO;
import com.corpgovernment.travelstandard.entity.db.*;
import com.corpgovernment.travelstandard.enums.TrainTransferCarModelEnum;
import com.corpgovernment.travelstandard.vo.*;
import com.corpgovernment.travelstandard.vo.train.SaveTrainTransferControlRequestVO;
import com.corpgovernment.travelstandard.vo.train.TrainTransferControlVO;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jhxue
 * @create 2022-05-12-18:05
 */
@Component
public class TrainTransferStandardConvert {

	public MbTravelStandardTrainTransfer convertToTravelStandardCar(TrainTransferStandardDTO airportTransferStandard) {
		if (airportTransferStandard == null) {
			return null;
		}
		MbTravelStandardTrainTransfer travelStandardCar = new MbTravelStandardTrainTransfer();
		travelStandardCar.setOrgId(airportTransferStandard.getOrgId());
		travelStandardCar.setName(airportTransferStandard.getName());
		travelStandardCar.setModelSwitch(airportTransferStandard.getModelSwitch());
		travelStandardCar.setModelControlType(airportTransferStandard.getModelControlType());
		travelStandardCar.setPriceSwitch(airportTransferStandard.getPriceSwitch());
		travelStandardCar.setPriceUpperLimit(airportTransferStandard.getPriceUpperLimit());
		travelStandardCar.setPriceControlType(airportTransferStandard.getPriceControlType());
		travelStandardCar.setCitySwitch(airportTransferStandard.getCitySwitch());
		travelStandardCar.setCityControlType(airportTransferStandard.getCityControlType());
		return travelStandardCar;
	}

	public List<MbTravelstandCarModel> convertTravelStandardCarModel(Long tsId) {
		if (tsId == null) {
			return new ArrayList<>();
		}
		return Arrays.stream(TrainTransferCarModelEnum.values()).map(e -> {
			MbTravelstandCarModel carModel = new MbTravelstandCarModel();
			carModel.setTsCarId(tsId);
			carModel.setModelCode(e.getCode());
			carModel.setModelName(e.getName());
			carModel.setTsType(TravelStandardTypeEnum.TrainTransfer.getCode());
			carModel.setDatachangeCreatetime(new Date());
			carModel.setDatachangeLasttime(new Date());
			return carModel;
		}).collect(Collectors.toList());
	}

	/**
	 * 对rc根据type进行分组，并转换为node
	 *
	 * @param reasonCodes
	 * @return
	 */
	public static Map<String, List<NodeVO>> groupReasonCodeByType(List<MbTravelstandReasonCode> reasonCodes) {
		if (CollectionUtils.isEmpty(reasonCodes)) {
			return new HashMap<>();
		}
		Map<String, List<NodeVO>> datas = new HashMap<>();
		for (ReasonCodeTypeEnum reasonCodeTypeEnum : ReasonCodeTypeEnum.values()) {
			List<NodeVO> nodes = new ArrayList<>();
			for (MbTravelstandReasonCode reasonCodeVo : reasonCodes) {
				if (reasonCodeVo.getTsRcType().equals(reasonCodeTypeEnum.getCode())) {
					NodeVO node = new NodeVO();
					node.setIsChecked(reasonCodeVo.getIsChecked());
					node.setName(reasonCodeVo.getName());
					node.setId(String.valueOf(reasonCodeVo.getId()));
					node.setCode(reasonCodeTypeEnum.getCode());
					nodes.add(node);
				}
			}
			datas.put(reasonCodeTypeEnum.getCode(), nodes);
		}
		return datas;
	}

	public TrainTransferControlVO convertToControl(MbTravelStandardTrainTransfer travelStandardTrainTransfer,
												   List<TravelStandardPost> travelStandardPosts,
												   List<MbTravelstandReasonCode> travelStandardReasonCodes,
												   List<MbTravelstandCarModel> travelStandardCarModels,
												   List<MbTravelStandCarCity> travelStandCarCities) {
		if (travelStandardTrainTransfer == null) {
			return null;
		}
		Map<String, List<NodeVO>> dealReasonCodeVos = groupReasonCodeByType(travelStandardReasonCodes);
		TrainTransferControlVO transferControl = new TrainTransferControlVO();
		transferControl.setOrgId(travelStandardTrainTransfer.getOrgId());
		transferControl.setTitle(travelStandardTrainTransfer.getName());
		transferControl.setId(String.valueOf(travelStandardTrainTransfer.getId()));
		transferControl.setProductSwitch(travelStandardTrainTransfer.getProductSwitch());
		String scopeIds = Optional.ofNullable(travelStandardPosts).orElse(new ArrayList<>()).stream()
								  .map(TravelStandardPost::getPostid)
								  .map(String::valueOf).collect(Collectors.joining(","));
		transferControl.setJobScopeId(scopeIds);
		//价格控制
		PriceControlVO priceControl = new PriceControlVO();
		priceControl.setStatus(travelStandardTrainTransfer.getPriceSwitch());
		priceControl.setPriceCeiling(travelStandardTrainTransfer.getPriceUpperLimit());
		priceControl.setPriceRcSet(travelStandardTrainTransfer.getPriceControlType());
		priceControl.setPriceRcCheckList(dealReasonCodeVos.get(ReasonCodeTypeEnum.CP.getCode()));
		transferControl.setPriceControl(priceControl);
		//车型控制
		ModelControlVO modelControl = new ModelControlVO();
		modelControl.setStatus(travelStandardTrainTransfer.getModelSwitch());
		modelControl.setCarTypeList(TrainTransferCarModelEnum.getCheckedNodeByCode(travelStandardCarModels));
		modelControl.setModelRcSet(travelStandardTrainTransfer.getModelControlType());
		modelControl.setModelRcCheckList(dealReasonCodeVos.get(ReasonCodeTypeEnum.CM.getCode()));
		transferControl.setModelControl(modelControl);
		//城市控制
		CityControl cityControl = new CityControl();
		cityControl.setStatus(travelStandardTrainTransfer.getCitySwitch());
		cityControl.setCarCityRcSet(travelStandardTrainTransfer.getCityControlType());
		cityControl.setCarCityRcCheckList(dealReasonCodeVos.get(ReasonCodeTypeEnum.CC.getCode()));
		CarCityControlVo carCityControlVo = new CarCityControlVo();
		carCityControlVo.setCityVos(Optional.ofNullable(travelStandCarCities).orElse(new ArrayList<>()).stream().map(i -> {
			CarCityVo vo = new CarCityVo();
			BeanUtils.copyProperties(i, vo);
			return vo;
		}).collect(Collectors.toList()));
		carCityControlVo.setControlType(CollectionUtils.isEmpty(travelStandCarCities) ? 0 : travelStandCarCities.get(0).getControlType());
		cityControl.setCarCityControlVo(carCityControlVo);
		transferControl.setCityControl(cityControl);
		return transferControl;
	}

	public List<TrainTransferControlVO> convertToControls(List<MbTravelStandardTrainTransfer> travelStandardTrainTransfers,
														  List<TravelStandardPost> travelStandardPosts,
														  List<MbTravelstandReasonCode> travelStandardReasonCodes,
														  List<MbTravelstandCarModel> travelStandardCarModels,
														  List<MbTravelStandCarCity> travelStandCarCities) {
		Map<Long, List<TravelStandardPost>> postMap = travelStandardPosts.stream().collect(Collectors.groupingBy(TravelStandardPost::getTsid));
		Map<Long, List<MbTravelstandReasonCode>> reasonCodeMap = travelStandardReasonCodes.stream().collect(Collectors.groupingBy(MbTravelstandReasonCode::getTsId));
		Map<Long, List<MbTravelstandCarModel>> carModelMap = travelStandardCarModels.stream().collect(Collectors.groupingBy(MbTravelstandCarModel::getTsCarId));
		Map<Long, List<MbTravelStandCarCity>> carCityMap = travelStandCarCities.stream().collect(Collectors.groupingBy(MbTravelStandCarCity::getTsid));
		return travelStandardTrainTransfers.stream().map(e -> {
			Long tsId = e.getId();
			return convertToControl(e, postMap.get(tsId), reasonCodeMap.get(tsId), carModelMap.get(tsId), carCityMap.get(tsId));
		}).collect(Collectors.toList());
	}

	public List<PostVO> convertToPostVO(List<MbPostInfo> postInfos) {
		if (CollectionUtils.isEmpty(postInfos)) {
			return new ArrayList<>();
		}
		return postInfos.stream().map(e -> {
			PostVO postVo = new PostVO();
			postVo.setId(e.getId());
			postVo.setOrgId(e.getOrgId());
			postVo.setName(e.getName());
			return postVo;
		}).collect(Collectors.toList());
	}

	public MbTravelStandardTrainTransfer convertToNowTravelStandard(MbTravelStandardTrainTransfer travelStandardTrainTransfer, SaveTrainTransferControlRequestVO request) {
		if (travelStandardTrainTransfer == null || request == null) {
			return null;
		}
		ModelControlVO modelControl = request.getModelControl();
		PriceControlVO priceControl = request.getPriceControl();
		CityControl cityControl = request.getCityControl();
		if (modelControl != null) {
			travelStandardTrainTransfer.setModelSwitch(modelControl.getStatus());
			travelStandardTrainTransfer.setModelControlType(modelControl.getModelRcSet());
		}
		if (priceControl != null) {
			travelStandardTrainTransfer.setPriceSwitch(priceControl.getStatus());
			travelStandardTrainTransfer.setPriceControlType(priceControl.getPriceRcSet());
			travelStandardTrainTransfer.setPriceUpperLimit(priceControl.getPriceCeiling());
		}
		if (cityControl != null) {
			travelStandardTrainTransfer.setCitySwitch(cityControl.getStatus());
			travelStandardTrainTransfer.setCityControlType(cityControl.getCarCityRcSet());
		}
		return travelStandardTrainTransfer;
	}

	public TrainTransferStandardDetailResponseBO convertToDetailBO(TrainTransferControlVO airportTransferControl) {
		if (airportTransferControl == null) {
			return TrainTransferStandardDetailResponseBO.isEmpty();
		}
		TrainTransferStandardDetailResponseBO response = new TrainTransferStandardDetailResponseBO();
		response.setTitle(airportTransferControl.getTitle());
		response.setId(airportTransferControl.getId());
		response.setJobScopeId(airportTransferControl.getJobScopeId());
		response.setOrgId(airportTransferControl.getOrgId());
		response.setPriceControl(this.convertToPriceControlBO(airportTransferControl.getPriceControl()));
		response.setModelControl(this.convertToModelControlBO(airportTransferControl.getModelControl()));
		response.setCarCityControl(this.convertToCarCityControlBO(airportTransferControl.getCityControl()));
		response.setProductSwitch(airportTransferControl.getProductSwitch());
		return response;
	}

	public CarCityControl convertToCarCityControlBO(CityControl cityControl) {
		if (cityControl == null) {
			return null;
		}
		CarCityControl bo = new CarCityControl();
		bo.setStatus(cityControl.getStatus());
		bo.setCarCityRcCheckList(this.convertToNodeBO(cityControl.getCarCityRcCheckList()));
		bo.setCarCityRcSet(cityControl.getCarCityRcSet());
		CarCityControlVo carCityControlVo = cityControl.getCarCityControlVo();
		com.corpgovernment.api.travelstandard.vo.car.CarCityControlVo carCityControlVo1 = new com.corpgovernment.api.travelstandard.vo.car.CarCityControlVo();
		carCityControlVo1.setControlType(carCityControlVo.getControlType());
		List<com.corpgovernment.api.travelstandard.vo.car.CarCityVo> cityVos = new ArrayList<>();
		for (CarCityVo cityVo : carCityControlVo.getCityVos()) {
			com.corpgovernment.api.travelstandard.vo.car.CarCityVo carCityVo = new com.corpgovernment.api.travelstandard.vo.car.CarCityVo();
			BeanUtils.copyProperties(cityVo, carCityVo);
			cityVos.add(carCityVo);
		}
		carCityControlVo1.setCityVos(cityVos);
		bo.setCarCityControlVo(carCityControlVo1);
		return bo;
	}

	private ModelControl convertToModelControlBO(ModelControlVO modelControl) {
		if (modelControl == null) {
			return null;
		}
		ModelControl bo = new ModelControl();
		bo.setStatus(modelControl.getStatus());
		bo.setModelRcSet(modelControl.getModelRcSet());
		bo.setCarTypeList(this.convertToNodeBO(modelControl.getCarTypeList()));
		bo.setModelRcCheckList(this.convertToNodeBO(modelControl.getModelRcCheckList()));
		return bo;
	}

	private List<Node> convertToNodeBO(List<NodeVO> voList) {
		if (CollectionUtils.isEmpty(voList)) {
			return new ArrayList<>();
		}
		return voList.stream().map(this::convertToNodeBO).collect(Collectors.toList());
	}

	private Node convertToNodeBO(NodeVO vo) {
		if (vo == null) {
			return null;
		}
		Node node = new Node();
		node.setId(vo.getId());
		node.setName(vo.getName());
		node.setCode(vo.getCode());
		node.setIsChecked(vo.getIsChecked());
		return node;
	}

	private PriceControl convertToPriceControlBO(PriceControlVO priceControl) {
		if (priceControl == null) {
			return null;
		}
		PriceControl bo = new PriceControl();
		bo.setStatus(priceControl.getStatus());
		bo.setPriceCeiling(priceControl.getPriceCeiling().intValue());
		bo.setPriceRcSet(priceControl.getPriceRcSet());
		bo.setPriceRcCheckList(this.convertToNodeBO(priceControl.getPriceRcCheckList()));
		return bo;
	}
}
